package com.ziytek.web.citizen.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * @author fenghx
 * @version 1.0
 * @className GzipUtil
 * Description: GZIP压缩解压算法
 * @date 2024/3/7 16:14
 */
@Slf4j
public class GzipUtil {
    /**
     * 使用 gzip 进行压缩.
     *
     * @param str 压缩前的文本
     * @return 压缩后的文本（BASE64 编码）
     */
    public static String gzip(final String str) {
        try {
            if (str == null || str.isEmpty()) {
                return str;
            }

            String gzipStr;

            byte[] compressed;
            ByteArrayOutputStream out = null;
            GZIPOutputStream gzipOutputStream;
            try {
                out = new ByteArrayOutputStream();
                gzipOutputStream = new GZIPOutputStream(out);
                gzipOutputStream.write(str.getBytes());
                gzipOutputStream.close();
                compressed = out.toByteArray();
                gzipStr = new String(Base64.encodeBase64(compressed), StandardCharsets.UTF_8);
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (final IOException e) {
                        log.error("字符串数据压缩异常:", e);
                    }
                }
            }

            return gzipStr;
        } catch (Exception ignored) {

        }

        return str;
    }

    /**
     * 使用 gzip 进行解压缩.
     *
     * @param compressedStr 压缩后的文本（BASE64 编码）
     * @return 解压后的文本
     * @throws IOException 如果解压异常
     */
    public static String unGzip(final String compressedStr) throws IOException {
        if (null == compressedStr || compressedStr.isEmpty()) {
            return compressedStr;
        }

        String ret;
        ByteArrayOutputStream out = null;
        ByteArrayInputStream in = null;
        GZIPInputStream zin = null;
        try {
            final byte[] compressed = Base64.decodeBase64(compressedStr.getBytes());
            out = new ByteArrayOutputStream();
            in = new ByteArrayInputStream(compressed);
            zin = new GZIPInputStream(in);
            final byte[] buffer = new byte[1024];
            int offset;
            while ((offset = zin.read(buffer)) != -1) {
                out.write(buffer, 0, offset);
            }

            ret = out.toString("UTF-8");
        } finally {
            if (zin != null) {
                try {
                    zin.close();
                } catch (final IOException e) {
                    log.error("字符串数据解缩异常0001:", e);
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (final IOException e) {
                    log.error("字符串数据解缩异常0002:", e);
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (final IOException e) {
                    log.error("字符串数据解缩异常0003:", e);
                }
            }
        }

        return ret;
    }
}
